
#include "EditorProcs.h"

#include <iostream>
#include <fstream>
#include <vector>
#include <set>

#include <cstdlib>
#include <thread>
//#include <string>
#include <string>
#include <iomanip>

#define GLM_FORCE_RADIANS
#include <glm/gtx/quaternion.hpp>

#include "BSP.h"
#include "globals.h"

#include "Editor.h"
#include "TextureWindow.h"

#include "leak.h"


using namespace std;


map< string, void (*)( char* ) > editor_procs = create_map<string, void (*)( char* )>	("LoadFile",			LoadFile			)
																						("SaveFile",			SaveFile			)
																						("CreateBoxBrush",		CreateBoxBrush		)
																						("CreateBoxBrushBB",	CreateBoxBrushBB	)
																						("AddMesh",				AddMesh				)
																						("Select",				Select				)
																						("MoveBuilderBrush",	MoveBuilderBrush	)
																						("RotateSelected",		RotateSelected		)
																						("FreezeTexture",		FreezeTexture		)
																						("ResetTexture",		ResetTexture		)
																						("DeleteSelected",		DeleteSelected		)
																						("CopySelected",		CopySelected		)
																						("SetTexture",			SetTexture			)
																						("FlushTextures",		FlushTextures		)
																						("GridSize",			GridSize			)
																						("PointSnap",			PointSnap			)
																						("SetMode",				SetMode				)
																						("ClearSelection",		ClearSelection		);


void RunCommand( string line ) {

	if( line.length() < 3 )
	{
		return;
	}

	char line_copy[100];
	strcpy( line_copy, line.c_str() );


	string com = strtok( line_copy, " " );

	char* params = strtok( NULL, "\0" );

	auto proc = editor_procs.find( com );

	if( proc == editor_procs.end() )
	{
		cout << "Command not found!" << endl;
		return;
	}
	cout << com << endl;
	//if( params != NULL )
	//{
		(proc->second)( params );
	//}

}

vector<char*> Tokenize( char* str, const char* delims ) {

	vector<char*> toks;
	char* tok = strtok( str, delims );
	while( tok != NULL )
	{
		toks.push_back( tok );
		tok = strtok( NULL, delims );
	}

	return toks;

}

void LoadFile( char* file_name ) {

	render_paused = true;

	lock_guard<mutex> render_lock(g_render_state.render_mtx);
		
	ifstream in_file( file_name );
	
	if ( !in_file )
    {
		cout << "Cant open file!  ( \"" << file_name << "\" )" << endl;
        return;
    }

	if( !g_brushes.empty() )
	{
		g_brushes.clear();
	}


	FlushTextures((char*)"");

	//int num_brushes = 512;
	//g_brushes = (Brush*)operator new(sizeof(Brush) * num_brushes);
	//g_brushes = new Brush[ num_brushes ];
	int num_brushes = 0;
	
	vector<float> tex_vecs;
	tex_vecs.reserve( 512 * 11 );

	string str;
	while(getline(in_file, str))
	{
		cout << str << endl;
		if(str.find("Number of brushes") != string::npos)
		{

		} else
		if(str.find("textures") != string::npos)
		{
			while(str.find("{") == string::npos)
			{
				getline(in_file, str);
			}
			getline(in_file, str);

			while(str.find("}") == string::npos)
			{
				char cstr[128];
				strcpy (cstr, str.c_str());
				char * p = strtok (cstr, " ()[]\t");

				cout << cstr << endl;
				Renderer::LoadTexture(p);
				getline(in_file, str);
			}
		} else
		if(str.find("brush") != string::npos)
		{
			while(str.find("{") == string::npos)
			{
				getline(in_file, str);
			}
			getline(in_file, str);

			int sides_index = 0;

			vector<float> sides;
			sides.reserve(256 * 3);

			while(str.find("}") == string::npos)
			{
				if(str.find("side") != string::npos)
				{
					char cstr[128];
					strcpy (cstr, str.c_str());

					char * p = strtok (cstr, " ()[]\t");
					
					for(int i = 0; i < 9; i++)
					{
						p = strtok(NULL, " ()[]\t");
						//sides[sides_index] = atof(p);
						sides.push_back(stof(p));
						cout << p << endl;
						sides_index++;
					}
					for(int i = 0; i < 11; i++)
					{
						p = strtok(NULL, " ()[]\t");
						tex_vecs.push_back(stof(p));
					}

				}

				getline(in_file, str);
			}

			cout << "before shrink: " << sides.capacity() << endl;
			sides.shrink_to_fit();
			cout << "after shrink: " << sides.capacity() << endl;
			//new(&g_brushes[num_brushes])Brush(sides);
			//g_brushes[num_brushes] = Brush(sides);

			//g_brushes.push_back( Brush(sides) );
			g_brushes.emplace_back(sides);

			num_brushes++;
		} else
		if(str.find("static_mesh") != string::npos)
		{
			while(str.find("{") == string::npos)
			{
				getline(in_file, str);
			}
			getline(in_file, str);

			g_static_meshes.emplace_back();
			
			char cstr[128];

			while(str.find("}") == string::npos)
			{
				if(str.find("name") != string::npos)
				{
					strcpy (cstr, str.c_str());
					char * p = strtok (cstr, " ()[]\t");
					p = strtok(NULL, " ()[]\t");

					g_static_meshes[g_static_meshes.size() - 1].set_name(p);
				} else
				if(str.find("file") != string::npos)
				{
					strcpy (cstr, str.c_str());
					char * p = strtok (cstr, " ()[]\t");
					p = strtok(NULL, " ()[]\t");

					g_static_meshes[g_static_meshes.size() - 1].LoadFromFile(p);
				} else
				if(str.find("angles") != string::npos)
				{
					glm::vec3 axis;
					strcpy (cstr, str.c_str());
					char * p = strtok (cstr, " ()[]\t");

					p = strtok(NULL, " ()[]\t");
					axis[0] = atof(p);
					p = strtok(NULL, " ()[]\t");
					axis[1] = atof(p);
					p = strtok(NULL, " ()[]\t");
					axis[2] = atof(p);

					float angle;
					p = strtok(NULL, " ()[]\t");
					angle = atof(p);
					//angles = glm::radians(angles);
					angle = glm::radians(angle);

					glm::quat q = glm::angleAxis(angle, axis);

					g_static_meshes[g_static_meshes.size() - 1].SetMatrix(glm::toMat4(q));
					//g_static_meshes[g_static_meshes.size() - 1].SetAngles(angles[0], angles[1], angles[2]);

				} else
				if(str.find("pos") != string::npos)
				{
					glm::vec3 pos;
					strcpy (cstr, str.c_str());
					char * p = strtok (cstr, " ()[]\t");

					p = strtok(NULL, " ()[]\t");
					pos[0] = atof(p);
					p = strtok(NULL, " ()[]\t");
					pos[1] = atof(p);
					p = strtok(NULL, " ()[]\t");
					pos[2] = atof(p);

					//g_static_meshes[g_static_meshes.size() - 1].Move(pos[0], pos[1], pos[2]);
					g_static_meshes[g_static_meshes.size() - 1].SetPos(pos[0], pos[1], pos[2]);
				}
				getline(in_file, str);
			}
		} else
		if(str.find("sky_camera") != string::npos)
		{
			g_entities.emplace_back(new SkyCamera());
			g_entities[g_entities.size()-1]->Import(in_file);
			/*while(str.find("{") == string::npos)
			{
				getline(in_file, str);
			}
			getline(in_file, str);

			//g_entities.push_back(std::unique_ptr<BaseEntity>(new SkyCamera()));
			g_entities.emplace_back(new SkyCamera());

			char cstr[128];

			while(str.find("}") == string::npos)
			{
				if(str.find("pos") != string::npos)
				{
					glm::vec3 pos;
					strcpy (cstr, str.c_str());
					char * p = strtok (cstr, " ()[]\t");

					p = strtok(NULL, " ()[]\t");
					pos[0] = atof(p);
					p = strtok(NULL, " ()[]\t");
					pos[1] = atof(p);
					p = strtok(NULL, " ()[]\t");
					pos[2] = atof(p);

					g_entities[g_entities.size()-1]->SetPos(pos[0], pos[1], pos[2]);
				}
				getline(in_file, str);
			}*/
		}
	}

	//for(int i = 0; i < num_brushes; i += 1)
	//{
	//	g_brushes[i].InitializeMesh();
	//}

	g_num_brushes = num_brushes;

	vector<thread> threads;

	int num_threads = min(thread::hardware_concurrency(), (unsigned int)g_num_brushes);
	for( int i = 0;  i < num_threads; i++ )
	{
		threads.push_back( thread([&](int id)->void
				{
					auto brush_it = g_brushes.begin();
					for( int k = 0; k < id; k++ )
					{
						brush_it++;
					}
					for( ; brush_it != g_brushes.end(); )
					{
						(*brush_it).InitializeMesh();
						(*brush_it).UpdateUVs();
						for( int k = 0; k < num_threads && brush_it != g_brushes.end(); k++ )
						{
							brush_it++;
						}
						if(brush_it == g_brushes.end())
						{
							break;
						}
					}
				}, i) );
	}

	for( int i = 0;  i < num_threads; i++ )
	{
		threads[i].join();
	}

	auto vec_it = tex_vecs.begin();
	for( auto brush_it = g_brushes.begin(); brush_it != g_brushes.end(); brush_it++ )
	{
		(*brush_it).SetTexVec( vec_it );
		(*brush_it).UpdateUVs();
	}

	in_file.close();

	render_paused = false;

	cout << g_num_brushes << endl;
	
	//delete[] threads;

}

static float Round(float val, float eps){

	int i_val = static_cast<int>(val / eps);
	float diff = val - static_cast<float>(i_val * eps);
	if(diff > eps/2.0f)
	{
		i_val++;
	} else
		if(diff < -eps/2.0f)
		{
			i_val--;
		}
	return  static_cast<float>(i_val * eps);
}

void SaveFile( char* name ) {

	ofstream out_file( name );

	if ( !out_file )
    {
		cout << "Cant write file!  ( \"" << out_file << "\" )" << endl;
        return;
    }

	FlushTextures((char*)"");

	out_file << "Number of brushes = " << g_brushes.size() << endl;

	out_file << "textures" << endl;
	out_file << "{" << endl;

	for(auto texture_name_it = Renderer::texture_names.begin();
			 texture_name_it != Renderer::texture_names.end(); texture_name_it++)
	{
		out_file << "\t" << (*texture_name_it) << endl;
	}

	out_file << "}" << endl;

	for( auto brush = g_brushes.begin(); brush != g_brushes.end(); brush++ )
	{
		out_file << "brush" << endl << "{" << endl;

		const vector<Poly>& polys = (*brush).polygons();

		for( auto poly = polys.begin(); poly != polys.end(); poly++ )
		{
			out_file << "\tside ";

			out_file << "( " << Round((*poly).points[0], epsilon) << " " << Round((*poly).points[1], epsilon) << " " << Round((*poly).points[2], epsilon) << " ) ";
			out_file << "( " << Round((*poly).points[3], epsilon) << " " << Round((*poly).points[4], epsilon) << " " << Round((*poly).points[5], epsilon) << " ) ";
			out_file << "( " << Round((*poly).points[6], epsilon) << " " << Round((*poly).points[7], epsilon) << " " << Round((*poly).points[8], epsilon) << " ) ";
			out_file << "[ " << Round((*poly).tex_vec[0][0], epsilon) << " " << Round((*poly).tex_vec[0][1], epsilon) << " " << Round((*poly).tex_vec[0][2], epsilon) << " " << Round((*poly).tex_vec[0][3], epsilon) << " ] ";
			out_file << "[ " << Round((*poly).tex_vec[1][0], epsilon) << " " << Round((*poly).tex_vec[1][1], epsilon) << " " << Round((*poly).tex_vec[1][2], epsilon) << " " << Round((*poly).tex_vec[1][3], epsilon) << " ] ";
			out_file << (*poly).tex_angle << " " << (*poly).tex_id << " " << (*poly).smoothing_group;
			out_file << endl;
		}

		out_file << "}" << endl;
	}

	for(auto& st_mesh : g_static_meshes)
	{
		out_file << "static_mesh" << endl << "{" << endl;

		out_file << "\tname\t" << st_mesh.name() << endl;
		out_file << "\tfile\t" << st_mesh.p_mesh()->file_name() << endl;

		glm::mat4x4 mat = st_mesh.model_matrix();
		glm::quat q = glm::quat_cast(mat);
		//glm::dvec3 angles = glm::degrees(glm::eulerAngles(q));
		glm::vec3 axis = glm::axis(q);
		axis[0] = Round(axis[0], epsilon);
		axis[1] = Round(axis[1], epsilon);
		axis[2] = Round(axis[2], epsilon);
		axis = glm::normalize(axis);
		float angle = glm::degrees(glm::angle(q));
		angle = Round(angle, epsilon);
		//glm::vec3 angles = glm::degrees(glm::an(mat));
		out_file << "\tangles\t" << axis[0] << " " << axis[1] << " " << axis[2] << " " << angle << endl;
		out_file << "\tpos\t\t" << mat[3][0] << " " << mat[3][1] << " " << mat[3][2] << endl;

		out_file << "}" << endl;
	}

	for(auto& p_ent : g_entities)
	{
		string out_str;
		p_ent->Export(out_str);
		out_file << out_str;
	}

	out_file.close();
}

void CreateBoxBrush( char* bbox ) {

	float box[6];
	
	vector<char*> params;

	Tokenize( bbox, const_cast<char*>(" ,") ).swap(params);

	if( params.size() != 6 )
	{
		cout << "Wrong dims!!!" << endl;
		return;
	}
	
	for( unsigned int i = 0; i < params.size(); i++ )
	{
		box[i] = stof( params[i] );
	}
	
	vector<float> sides;
	sides.reserve( 18 * 3 );

	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[2] );
	sides.push_back( box[0] );		sides.push_back( box[4] );		sides.push_back( box[2] );
	sides.push_back( box[3] );		sides.push_back( box[1] );		sides.push_back( box[2] );

	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[2] );
	sides.push_back( box[0] );		sides.push_back( box[4] );		sides.push_back( box[2] );
	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[5] );

	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[2] );
	sides.push_back( box[3] );		sides.push_back( box[1] );		sides.push_back( box[2] );
	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[5] );

	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[5] );
	sides.push_back( box[3] );		sides.push_back( box[1] );		sides.push_back( box[5] );
	sides.push_back( box[0] );		sides.push_back( box[4] );		sides.push_back( box[5] );

	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[5] );
	sides.push_back( box[3] );		sides.push_back( box[1] );		sides.push_back( box[5] );
	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[2] );

	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[5] );
	sides.push_back( box[0] );		sides.push_back( box[4] );		sides.push_back( box[5] );
	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[2] );

	render_paused = true;

	//if( g_brushes == nullptr )
	//{
		//g_brushes = (Brush*)operator new(sizeof(Brush) * 512);
		//g_brushes = new Brush[ 512 ];
	//}


	//new ( &g_brushes[ g_num_brushes ] ) Brush( sides );
	//g_brushes[ g_num_brushes ] = Brush( sides );
	//g_brushes[ g_num_brushes ].InitializeMesh();

	g_brushes.push_back( Brush( sides ) );
	auto it_last_brush = g_brushes.end();
	it_last_brush--;
	(*it_last_brush).InitializeMesh();
	(*it_last_brush).UpdateUVs();

	render_paused = false;
	g_num_brushes++;

}


void CreateBoxBrushBB( char* bbox ) {

	float box[6];
	

	box[0] = g_builder_brush->bbox_min()[0];
	box[1] = g_builder_brush->bbox_min()[1];
	box[2] = g_builder_brush->bbox_min()[2];

	box[3] = g_builder_brush->bbox_max()[0];
	box[4] = g_builder_brush->bbox_max()[1];
	box[5] = g_builder_brush->bbox_max()[2];

	vector<float> sides;
	sides.reserve( 18 * 3 );

	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[2] );
	sides.push_back( box[0] );		sides.push_back( box[4] );		sides.push_back( box[2] );
	sides.push_back( box[3] );		sides.push_back( box[1] );		sides.push_back( box[2] );

	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[2] );
	sides.push_back( box[0] );		sides.push_back( box[4] );		sides.push_back( box[2] );
	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[5] );

	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[2] );
	sides.push_back( box[3] );		sides.push_back( box[1] );		sides.push_back( box[2] );
	sides.push_back( box[0] );		sides.push_back( box[1] );		sides.push_back( box[5] );

	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[5] );
	sides.push_back( box[3] );		sides.push_back( box[1] );		sides.push_back( box[5] );
	sides.push_back( box[0] );		sides.push_back( box[4] );		sides.push_back( box[5] );

	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[5] );
	sides.push_back( box[3] );		sides.push_back( box[1] );		sides.push_back( box[5] );
	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[2] );

	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[5] );
	sides.push_back( box[0] );		sides.push_back( box[4] );		sides.push_back( box[5] );
	sides.push_back( box[3] );		sides.push_back( box[4] );		sides.push_back( box[2] );

	render_paused = true;

	//if( g_brushes == nullptr )
	//{
		//g_brushes = (Brush*)operator new(sizeof(Brush) * 512);
		//g_brushes = new Brush[ 512 ];
	//}

	//new ( &g_brushes[ g_num_brushes ] ) Brush( sides );
	//g_brushes[ g_num_brushes ] = Brush( sides );
	//g_brushes[ g_num_brushes ].InitializeMesh();
	g_brushes.push_back( Brush( sides ) );
	auto last_it = g_brushes.end();
	last_it--;
	(*last_it).InitializeMesh();
	(*last_it).UpdateUVs();

	render_paused = false;
	g_num_brushes++;

}

void AddMesh(char* str){
	g_static_meshes.push_back(GLStaticMesh());
	g_static_meshes[g_static_meshes.size()-1].LoadFromFile(str);
}

void Select( char* str ) {

	vector<char*> params;
	Tokenize( str, const_cast<char*>(" ,") ).swap(params);

	if( params.size() < 1 )
	{
		cout << "Wrong parameters" << endl;
	}

	if( strcmp( params[0], "builder_brush") == 0 )
	{
		g_builder_brush->set_selected( true );
	} else
	{
		if( strcmp( params[0], "brush") == 0 )
		{
			if( params.size() < 2 )
			{
				cout << "Wrong parameters" << endl;
			} else
			{
				int brush_index = atoi( params[1] );

				auto brush_it = g_brushes.begin();
				auto last_it = g_brushes.end();
				last_it--;
				while( brush_index > 0 && brush_it != last_it )
				{
					brush_it++;
					brush_index--;
				}

				g_selection_frame->Add( &(*brush_it) );
				(*brush_it).set_selected(true);

				/*if( brush_index >= 0 && brush_index < g_num_brushes )
				{
					g_selection_frame->Add( &g_brushes[ brush_index ] );
				} else
				{
					cout << "Wrong index" << endl;
				}*/
			}
		}
	}

}

void MoveBuilderBrush( char* str ) {

	vector<char*> params;
	Tokenize( str, const_cast<char*>(" ,") ).swap(params);

	if( params.size() < 3 )
	{
		cout << "Wrong parameters" << endl;
	}

	float v[3] = {	stof( params[0] ),
					stof( params[1] ),
					stof( params[2] ) };

	g_builder_brush->Move( v );

}

void RotateSelected( char* str ) {

	if( g_selection_frame->Empty() )
	{
		return;
	}

	vector<char*> params;
	Tokenize( str, const_cast<char*>(" ,") ).swap(params);
	if( params.size() != 4 )
	{
		cout << "Wrong parameters" << endl;
		return;
	}

	float angle = stof( params[0] );
	float axis[3];
	axis[0] = stof( params[1] );
	axis[1] = stof( params[2] );
	axis[2] = stof( params[3] );

	g_selection_frame->Rotate( axis, angle );
}

void FreezeTexture( char* str ) {

	if( str == NULL )
	{
		cout << "Wrong parameters" << endl;
		return;
	}

	vector<char*> params;
	Tokenize( str, const_cast<char*>(" ,") ).swap(params);
	if( params.size() != 1 )
	{
		cout << "Wrong parameters" << endl;
		return;
	}

	bool b;

	if( strcmp( params[0], "on" ) == 0 )
	{
		b = true;
	} else
	{
		if( strcmp( params[0], "off" ) == 0 )
		{
			b = false;
		} else
		{
			cout << "Wrong parameters" << endl;
			return;
		}
	}

	g_selection_frame->SetFreezeTexture( b );

}

void ResetTexture( char* ) {

	g_selection_frame->ResetTexture();

}

void DeleteSelected( char* str ) {

	g_selection_frame->DeleteSelection();

}

void CopySelected( char* str ) {
	g_selection_frame->CopySelection();
}

void SetTexture( char* str ) {

	vector<char*> params;
	Tokenize( str, " ," ).swap(params);

	g_selection_frame->SetTexrure( atoi(params[0]) );
}

void FlushTextures( char* ) {

	set<unsigned int> used_textures;

	for(auto brush_it = g_brushes.begin(); brush_it != g_brushes.end(); brush_it++)
	{
		(*brush_it).GetUsedTextures(used_textures);
	}

	vector<unsigned int> conversions;
	conversions.reserve(used_textures.size());

	for(auto tex_it : used_textures)
	{
		conversions.push_back(tex_it);
	}

	int num_deleted = 0;
	unsigned int i;
	for(i = 0; i < conversions.size(); i++)
	{
		if(i != conversions[i])
		{
			for(unsigned int j = i; j < conversions[i]-num_deleted; j++)
			{
				Renderer::DeleteTexture(j);
				num_deleted++;
			}
			for(auto brush_it = g_brushes.begin(); brush_it != g_brushes.end(); brush_it++)
			{
				(*brush_it).ReplaceTexture(conversions[i], i);
			}
		}
	}

	for(unsigned int k = i; k < Renderer::textures.size(); k++)
	{
		Renderer::DeleteTexture(k);
	}
/*
	unsigned int list_content[256];
	int u = 0;
	for(auto tex_it : used_textures)
	{
		list_content[u] = tex_it;
		u++;
	}
	list_content[u] = 666;

	int t;
*/
}

void GridSize( char* str ) {

	vector<char*> params;
	Tokenize( str, " ," ).swap(params);

	if( params.size() < 1 )
	{
		cout << "Wrong parameters" << endl;
	}

	g_render_state.grid_size = atoi( params[0] );
}

void PointSnap( char* str ) {

	vector<char*> params;
	Tokenize( str, " ," ).swap(params);
	if( params.size() != 1 )
	{
		cout << "Wrong parameters" << endl;
	}

	if( strcmp( params[0], "on" ) == 0 )
	{
		g_render_state.point_snap = true;
	} else
	{
		if( strcmp( params[0], "off" ) == 0 )
		{
			g_render_state.point_snap = false;
		} else
		{
			cout << "Wrong parameter" << endl;
		}
	}
}

void SetMode( char* str ) {
	vector<char*> params;
	Tokenize( str, " ," ).swap(params);
	if( params.size() != 1 )
	{
		cout << "Wrong parameters" << endl;
	}

	if( strcmp( params[0], "edit" ) == 0 )
	{
		g_selection_frame->set_mode( EDIT_MODE );
		g_tex_window->Hide();
	} else
	{
		if( strcmp( params[0], "select" ) == 0 )
		{
			g_selection_frame->set_mode( SELECT_MODE );
			g_tex_window->Hide();
		} else
		{
			if( strcmp( params[0], "texture" ) == 0 )
			{
				g_selection_frame->set_mode( TEX_MODE );
				g_tex_window->Show();
			} else
			{
				cout << "Wrong parameter" << endl;
			}
		}
	}

}
/*
void SelectBrush( char* str ) {

	vector<char*> params;
	Tokenize( str, " ," ).swap(params);

	if( params.size() < 1 )
	{
		cout << "Wrong parameters" << endl;
	}

	int brush_index = atoi( params[0] );

	if( brush_index >= 0 && brush_index < g_num_brushes )
	{
		g_selection_frame->Add( &g_brushes[ brush_index ] );
	} else
	{
		cout << "Wrong index" << endl;
	}

}
*/
void ClearSelection( char* ) {

	g_selection_frame->Clear();

}
